package com.zhaopin.qa.jmeter.plugins.jsonschemaassertion.gui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

import org.apache.jmeter.assertions.gui.AbstractAssertionGui;
import org.apache.jmeter.gui.util.HorizontalPanel;
import org.apache.jmeter.gui.util.JSyntaxTextArea;
import org.apache.jmeter.gui.util.JTextScrollPane;
import org.apache.jmeter.testelement.TestElement;
import org.everit.json.schema.loader.SpecificationVersion;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;

import com.zhaopin.qa.jmeter.plugins.jsonschemaassertion.JSONSchemaAssertion;

public class JSONSchemaAssertionGui extends AbstractAssertionGui {

	private static final long				serialVersionUID = -7214082928244849158L;

	private JComboBox<SpecificationVersion>	versionCheckBox;
	private JTextField						fileSchema;
	private JSyntaxTextArea					textSchema;

	private static final String				notes			 = "if no item is selected, will use this rule:\n"
															   +
																   "    if there is \"$schema\": \"http://json-schema.org/draft-04/schema\" in the schema root, then Draft 4 will be used\n"
																   +
																   "    if there is \"$schema\": \"http://json-schema.org/draft-06/schema\" in the schema root, then Draft 6 will be used\n"
																   +
																   "    if there is \"$schema\": \"http://json-schema.org/draft-07/schema\" in the schema root, then Draft 7 will be used\n"
																   +
																   "    if none of these is found then Draft 4 will be assumed as default\n";

	/**
	 * The constructor.
	 */
	public JSONSchemaAssertionGui() {
		init();
	}

	@Override
	public String getLabelResource() {
		return "JSON Schema Assertion";
	}

	@Override
	public String getStaticLabel() {
		return "JSON Schema Assertion";
	}

	/**
	 * create Test Element
	 */
	@Override
	public TestElement createTestElement() {
		JSONSchemaAssertion el = new JSONSchemaAssertion();
		modifyTestElement(el);
		return el;
	}

	@Override
	public void modifyTestElement(TestElement inElement) {
		configureTestElement(inElement);
		if (versionCheckBox.getSelectedIndex() > -1) {
			((JSONSchemaAssertion) inElement).setSchemaVersion((SpecificationVersion) versionCheckBox.getSelectedItem());
		}
		((JSONSchemaAssertion) inElement).setSchemaFileName(fileSchema.getText());
		((JSONSchemaAssertion) inElement).setSchemaContent(textSchema.getText());
	}

	@Override
	public void clearGui() {
		super.clearGui();
		fileSchema.setText("");
		textSchema.setText("");
	}

	@Override
	public void configure(TestElement el) {
		super.configure(el);
		JSONSchemaAssertion assertion = (JSONSchemaAssertion) el;
		versionCheckBox.setSelectedItem(assertion.getSchemaVersion());
		fileSchema.setText(assertion.getSchemaFileName());
		textSchema.setText(assertion.getSchemaContent());
	}

	private void init() {
		setLayout(new BorderLayout(0, 10));
		setBorder(makeBorder());

		add(makeTitlePanel(), BorderLayout.NORTH);
		Box box = Box.createVerticalBox();
		box.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "JSON Schema"));

		box.add(Box.createVerticalStrut(8));
		box.add(createVersionPanel());
		box.add(Box.createVerticalStrut(8));
		box.add(createFilenamePanel());
		box.add(Box.createVerticalStrut(8));
		box.add(createScriptPanel());

		add(box, BorderLayout.CENTER);
	}

	private JPanel createVersionPanel() {
		JPanel panel = new HorizontalPanel();
		panel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Schema Version:"));
		versionCheckBox = new JComboBox<>(SpecificationVersion.values());
		versionCheckBox.setSelectedIndex(-1);

		JLabel icon = new JLabel("select version:");

		panel.add(icon);
		panel.add(versionCheckBox);

		ImageIcon imageIcon	= new ImageIcon(JSONSchemaAssertionGui.class.getClassLoader().getResource("help.png"));
		JLabel	  jLabel	= new JLabel(imageIcon);
		jLabel.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				JOptionPane.showMessageDialog(fileSchema, notes);
			}
		});
		panel.add(jLabel);

		panel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 10));
		return panel;
	}

	private JPanel createFilenamePanel() {
		JLabel label = new JLabel("File Name:");

		fileSchema = new JTextField();
		label.setLabelFor(fileSchema);

		JPanel panel = new JPanel(new BorderLayout(5, 0));
		panel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Schema file(overrides schema):"));
		panel.add(label, BorderLayout.WEST);
		panel.add(fileSchema, BorderLayout.CENTER);

		panel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 10));
		return panel;
	}

	private JPanel createScriptPanel() {

		JPanel panel = new JPanel(new BorderLayout());
		panel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Schema(说明：使用文件模板时，将不会使用输入框中的模板。二者只能二选一)"));

		textSchema = new JSyntaxTextArea(20, 20);
		textSchema.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JSON_WITH_COMMENTS);
		textSchema.setLineWrap(false);
		textSchema.setCodeFoldingEnabled(true);
		textSchema.setAntiAliasingEnabled(true);
		panel.add(new JTextScrollPane(textSchema), BorderLayout.CENTER);

		return panel;
	}
}
